package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.Category;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.mapper.CategoryMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Override
    public List<Category> getCategories() {

        List<Category> categories = categoryMapper.selectList(
                new LambdaQueryWrapper<Category>().orderByAsc(Category::getSort));

        //获取题目分类列表填充题目数量
        fiilCategoryQuestionCount(categories);

        return categories;
    }

    @Override
    public List<Category> getCategoryTree() {

        List<Category> categories = categoryMapper.selectList(
                new LambdaQueryWrapper<Category>().orderByAsc(Category::getSort));

        //获取题目分类列表填充题目数量
        fiilCategoryQuestionCount(categories);

//        categories.forEach(category -> {
//            List<Category> children = categories.stream().filter(child -> category.getParentId().equals(child.getParentId()))
//                    .collect(Collectors.toList());
//            category.setChildren(children);
//        });
        List<Category> buildTree=buildTree(categories);

        return buildTree;
    }

    @Override
    public void addCategory(Category category) {


       LambdaQueryWrapper<Category>cat=new LambdaQueryWrapper<>();
       cat.eq(Category::getName,category.getName());
       cat.eq(Category::getParentId,category.getParentId());
       cat.eq(Category::getSort,category.getSort());
        Long count = categoryMapper.selectCount(cat);
        if (count > 0) {
            log.error("当前父类别{}下，名为：{}子分类已经重复！",category.getParentId(),category.getName());
            throw new RuntimeException("当前父类下，已经存在同名的子分类，请另起它名！");
        }
       categoryMapper.insert(category);

    }

    @Override
    public void updateCategory(Category category) {
        categoryMapper.updateById(category);
    }

    @Override
    public void deleteCategory(Long id) {
        Category category = categoryMapper.selectById(id);
        if (category!=null && category.getParentId()==0){
            throw new RuntimeException("一级标题不可删除");
        }

        LambdaQueryWrapper<Category> eq = new LambdaQueryWrapper<Category>().eq(Category::getParentId, id);
        Long count = categoryMapper.selectCount(eq);
        if (count >0){
            throw new RuntimeException("该分类下有子分类，不可删除");
        }
        LambdaQueryWrapper<Question> eq1 = new LambdaQueryWrapper<Question>().eq(Question::getCategoryId, id);
        Long questioncount = questionMapper.selectCount(eq1);
        if(questioncount > 0){
            throw new RuntimeException("该分类下有题目信息，不可删除");
        }

        categoryMapper.deleteById(id);
    }

    private List<Category> buildTree(List<Category> categories) {

        Map<Long, List<Category>> collectMap = categories.stream().
                collect(Collectors.groupingBy(Category::getParentId));

        categories.forEach(category -> {
            List<Category> children = collectMap.getOrDefault(category.getId(), new ArrayList<>());
            category.setChildren(children);

            long childenCount = children.stream().mapToLong(c -> c.getCount() != null ? c.getCount() : 0L).sum();

            long questionCount=category.getCount()!=null? category.getCount():0L;

            category.setCount(questionCount + childenCount);

        });

        return categories.stream().filter(c->c.getParentId()==0).collect(Collectors.toList());

    }

    //辅助方法
    private void fiilCategoryQuestionCount(List<Category> categories) {

        List<Map<Long,Object>> questionCountList = questionMapper.getCategoryQuestionCount();

        Map<Long, Long> questionCountMap = questionCountList.stream().collect(Collectors.toMap(
                map -> Long.valueOf(map.get("category_id").toString()),
                map -> Long.valueOf(map.get("count").toString())
        ));

        categories.forEach(category -> {
            category.setCount(questionCountMap.getOrDefault(category.getId(), 0L));
        });

    }


















}